package com.lenovo.lcdm.dcm.common.util;

import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

import java.io.*;
import java.lang.reflect.Field;
import java.util.*;

public class ObjectUtil {

    public static <T> T deepCopy(T obj) {
        try {
            try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
                try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream)) {
                    objectOutputStream.writeObject(obj);
                }
                try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray())) {
                    try (ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream)) {
                        return (T) objectInputStream.readObject();
                    }
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);

        }
    }

    /**
     * 将Object对象里面的属性和值转化成Map对象
     *
     * @param obj
     * @return
     * @throws IllegalAccessException
     */
    public static Map<String, Object> objectToMap(Object obj) throws IllegalAccessException {
        Map<String, Object> map = new HashMap<String,Object>();
        Class<?> clazz = obj.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            String fieldName = field.getName();
            Object value = field.get(obj);
            map.put(fieldName, value);
        }
        return map;
    }

    /**
     * Check variables, if any variable is empty then return true, else return false
     * @param objects the objects need to be checked
     * @return if any variable is empty then return true, else return false
     */
    public static boolean isAnyEmpty(Object... objects){
        for(Object object:objects){
            if(object == null ||
                    (object instanceof String && StringUtils.isEmpty(object)) ||
                    (object instanceof Collection && CollectionUtils.isEmpty((Collection<?>) object)) ||
                    (object instanceof Map && CollectionUtils.isEmpty((Map<?,?>)object))){
                return true;
            }
        }
        return false;
    }

    /**
     * Check variables, if any variable is empty then return true, else return false
     * @param objects the objects need to be checked
     * @return if any variable is empty then return true, else return false
     */
    public static boolean isAllEmpty(Object... objects){
        for(Object object:objects){
            if(!(object == null ||
                    (object instanceof String && StringUtils.isEmpty(object)) ||
                    (object instanceof Collections && CollectionUtils.isEmpty((Collection<?>) object)) ||
                    (object instanceof Map && CollectionUtils.isEmpty((Map<?,?>)object)))){
                return false;
            }
        }
        return true;
    }

    /**
     *  批量反射更新字段值
     *  todo hhr common包升版本
     */
    public static void batchSetFieldValue(Object obj, Map<String, Object> fieldMap) {
        ReflectionUtils.doWithFields(obj.getClass(), field -> {
            Object value = fieldMap.get(field.getName());
            if (Objects.nonNull(value)) {
                boolean accessible = field.isAccessible();
                if (!accessible) {
                    field.setAccessible(true);
                }
                ReflectionUtils.setField(field, obj, value);
                if (!accessible) {
                    field.setAccessible(false);
                }
            }
        });
    }

}
